package org.smartboot.socket.server;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import org.smartboot.socket.MessageProcessor;
import org.smartboot.socket.StateMachineEnum;
import org.smartboot.socket.common.ChatMessage;
import org.smartboot.socket.transport.AioSession;
/**
 * @author laoliu
 * @since 1.0
 */
public class ChatServerProcessor implements MessageProcessor<ChatMessage> {
    /**
     * map:key是用户名，value是客户端的连接
     */
    private Map<String,AioSession> clients=new ConcurrentHashMap<>();
    /**
     * 用户名，和sessionid
     */
    private Map<String,String> names=new ConcurrentHashMap<>();
    @Override
    public void process(AioSession session, ChatMessage msg) {
        System.out.println( " get:"+msg+" to :");
        if(msg.getTo().equals(ChatMessage.TO._LOGIN.toString())){
            names.put(msg.getFrom(),session.getSessionID());
            sendToAll(msg);
            return;
        }
        if(names.containsKey(msg.getTo())){
            AioSession s= clients.get(names.get(msg.getTo()));
            sendMsgToSession(s,msg);
            return;
        }
    }
    public void sendMsgToSession(AioSession s,ChatMessage msg){
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream objectOutput = new ObjectOutputStream(byteArrayOutputStream);
            objectOutput.writeObject(msg);
            byte[] data = byteArrayOutputStream.toByteArray();
            //发一下内容的长度
            s.writeBuffer().writeInt(data.length);
            s.writeBuffer().write(data);
            s.writeBuffer().flush();
            objectOutput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void sendToAll(ChatMessage msg){

        for(AioSession s:clients.values()){
//            if(s==session)
//                continue;
            sendMsgToSession(s,msg);
        }
    }

    @Override
    public void stateEvent(AioSession session, StateMachineEnum stateMachineEnum, Throwable throwable) {
        switch (stateMachineEnum) {
            case NEW_SESSION:
                System.out.println("StateMachineEnum.NEW_SESSION");
                clients.put(session.getSessionID(), session);
                break;
            case INPUT_SHUTDOWN:
                System.out.println("StateMachineEnum.INPUT_SHUTDOWN");
                break;
            case PROCESS_EXCEPTION:
                System.out.println("StateMachineEnum.PROCESS_EXCEPTION");
                break;
            case DECODE_EXCEPTION:
                System.out.println("StateMachineEnum.DECODE_EXCEPTION");
                break;
            case INPUT_EXCEPTION:
                System.out.println("StateMachineEnum.INPUT_EXCEPTION");
                break;
            case OUTPUT_EXCEPTION:
                System.out.println("StateMachineEnum.OUTPUT_EXCEPTION");
                break;
            case SESSION_CLOSING:
                System.out.println("StateMachineEnum.SESSION_CLOSING");
                break;
            case SESSION_CLOSED:
                System.out.println("StateMachineEnum.SESSION_CLOSED");
                clients.remove(session.getSessionID());
                Iterator<Map.Entry<String, String>> iterator = names.entrySet().iterator();
                String name=null;
                while(iterator.hasNext()){
                    Map.Entry<String, String> e = iterator.next();
                    if(e.getValue().equals(session.getSessionID())){
                        name=e.getKey();
                        names.remove(name);
                        break;
                    }
                }
                //群发消息，退出了
                if(name!=null){
                    ChatMessage quit=new ChatMessage(name,ChatMessage.TO._ALL.toString(),name+"退出了");
                    sendToAll(quit);
                }

                break;

            default:
                System.out.println("StateMachineEnum.default");
        }
        if(throwable!=null)
        {
            throwable.printStackTrace();
        }
    }
}
